#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>

static int major;
static struct class *led_class;

static ssize_t led_write (struct file *file, const char __user *buf, size_t size, loff_t *offset) {
    char val;
    /* copy_from_user : get data from app */
    copy_from_user(&val, buf, 1);

    /* to set gpio register: out 1/0 */
    if (val) 
    {
        /* set gpio to let led on */
    } 
    else 
    {
        /* set gpio to let led off */
    }

    return 1;
}

static int led_open (struct inode *node, struct file *file) {
    /* 
     * enable gpio
     * configure pin as gpio
     * configure gpio as output 
    */
    return 0;
}

static const struct file_operations led_fops = {
	.owner		= THIS_MODULE,
    .open       = led_drv_open,
    .write      = led_drv_write,
};

static int __init led_init(void) {
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

    major = register_chrdev(0, "my_led", &led_fops);
    
    /* ioremap */

    led_class = create_class(THIS_MODULE, "myled");
    device_create(led_class, NULL, MKDEV(major, 0), NULL, "myled");     /* /dev/myled */

    return 0;
}

static void __exit led_exit(void) {
    device_destory(led_class, MKDEV(major, 0));
    class_destory(led_class);
    unregister_chrdev(major, "my_led");
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");